#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use pyo3::prelude::*;
use pyo3::types::PyList;
use std::{env, fs, path::Path};
use rfd::FileDialog;
use tauri::generate_handler;
use rfd::AsyncFileDialog;



fn main() {
     // 设置PYTHONPATH来包含虚拟环境中的site-packages目录
     let python_path = "./python/venv/Lib/site-packages";
     env::set_var("PYTHONPATH", &python_path);
     // 设置PYTHONEXECUTABLE来指向虚拟环境中的Python解释器
     let python_executable = "./python/venv/Scripts/python.exe";
     env::set_var("PYTHONEXECUTABLE", &python_executable);
     // 初始化Python解释器，确保可以使用Python API
    pyo3::prepare_freethreaded_python();
    // 启动Tauri应用
    tauri::Builder::default()
        .invoke_handler(generate_handler![greet,save_file])
        .run(tauri::generate_context!())
        .expect("Error while running Tauri application");
}

/// 调用Python函数
fn call_python_function() -> Result<Py<PyAny>, PyErr> {
    let path = Path::new("./python"); // 相对路径的python目录

    // 读取main.py文件的内容为字符串
    let py_app = fs::read_to_string(path.join("main.py"))
        .expect("Failed to read main.py");

    // 使用Python全局解释器锁执行Python代码
    Python::with_gil(|py| {
        let syspath = py
            .import_bound("sys")? // 获取sys模块
            .getattr("path")?  // 获取sys.path列表
            .downcast_into::<PyList>()?; // 转换为PyList类型
        syspath.insert(0, path)?;

        // 将main.py的内容作为一个Python模块加载，并获取其中的"function1"属性
        let app: Py<PyAny> = PyModule::from_code_bound(py, &py_app, "", "")?
        .getattr("function1")?
        .into();
        app.call0(py)
    })
}


#[tauri::command]
fn greet() -> String {
    match call_python_function() {
        Ok(result) => result.to_string(),
        Err(e) => {
            e.to_string()
        }
    }
}

/// 选择文件夹路径
fn _get_folderpath() -> Result<String, std::io::Error> {
    // 打开文件夹选择对话框
    let folder_path = FileDialog::new()
        .pick_folder();

    match folder_path {
        Some(path) => {
            Ok(path.to_str().unwrap().to_string())
        }
        None => {
            Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "No folder selected",
            ))
        }
    }
}


/// 选择文件路径
fn _get_filepath() -> Result<String, std::io::Error> {
    match FileDialog::new().add_filter("Text Files", &["xlsx"]).pick_file() {
        Some(path) => Ok(path.to_str().unwrap().to_string()),
        None => Err(std::io::Error::new(
            std::io::ErrorKind::Other,
            "No file selected",
        )),
    }
}

/// 返回当前执行程序的安装目录的绝对路径作为字符串
fn _get_install_dir_as_string() -> Option<String> {
    env::current_exe()
        .ok()?
        .parent()?
        .to_str()
        .map(|s| s.to_string())
}


#[tauri::command]
async fn save_file(base64_data: String) -> Result<String, String> {
    let file_path = AsyncFileDialog::new()
        .add_filter("Excel Files", &["xlsx"])
        .save_file()
        .await;

    match file_path {
        Some(path) => {
            match base64::decode(&base64_data) {
                Ok(decoded_data) => {
                    // 假设 FileHandle 提供了一个 path() 方法来获取 PathBuf
                    if let Err(err) = fs::write(path.path(), decoded_data) {
                        return Err(format!("Error writing file: {}", err));
                    }
                },
                Err(err) => {
                    return Err(format!("Error decoding base64 data: {}", err));
                },
            }
            Ok(String::from("File saved successfully."))
        },
        None => Err(String::from("User canceled the save dialog")),
    }
}